package com.shujia.spark.core

import org.apache.spark.rdd.RDD
import org.apache.spark.storage.StorageLevel
import org.apache.spark.{SparkConf, SparkContext}

object Demo22Cache {
  def main(args: Array[String]): Unit = {
    val conf: SparkConf = new SparkConf()
    conf.setMaster("local")
    conf.setAppName("Demo22Cache")

    val sc: SparkContext = new SparkContext(conf)

    val stuRDD: RDD[String] = sc.textFile("spark/data/stu/students.txt")

    val stuMapRDD: RDD[String] = stuRDD.map(line => {
      println("进入了map算子")
      line
    })

    /**
     * 可以使用cache()对多次使用的RDD进行缓存
     * 默认是缓存到内存中的
     * 相当于persist(StorageLevel.MEMORY_ONLY)
     * 所以还以通过persist结合StorageLevel来指定不同的缓存策略
     */
    //    stuMapRDD.cache()
    /**
     * 如何选择缓存策略：
     * 1、如果内存充足：直接MEMORY_ONLY
     * 2、如果内存放不下：使用MEMORY_AND_DISK_SER
     * 为什么需要序列化？
     * 可以尽可能的将数据缓存到内存中
     * 序列化反序列化所消耗的时间对比磁盘IO来说，代价更小
     */
    stuMapRDD.persist(StorageLevel.MEMORY_AND_DISK_SER)
    // 统计班级人数
    val clazzCntRDD: RDD[(String, Int)] = stuMapRDD.map(line => (line.split(",")(4), 1)).reduceByKey(_ + _)
    clazzCntRDD.foreach(println)

    // 统计性别人数
    val genderCntRDD: RDD[(String, Int)] = stuMapRDD.map(line => (line.split(",")(3), 1)).reduceByKey(_ + _)
    genderCntRDD.foreach(println)

    // 用完之后记得释放缓存，特别是在实时程序中
    stuMapRDD.unpersist()


  }

}
